
package com.x52im.rbchat.utils;

import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;

import java.util.LinkedList;
import java.util.List;

/**
 * 软键盘监听器助手
 *
 */
public class SoftKeyboardStateHelper implements
        ViewTreeObserver.OnGlobalLayoutListener {

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);

        void onSoftKeyboardClosed();
    }

    private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
    private final View activityRootView;
    private int lastSoftKeyboardHeightInPx;
    private boolean isSoftKeyboardOpened;

    public SoftKeyboardStateHelper(View activityRootView) {
        this(activityRootView, false);
    }

    public SoftKeyboardStateHelper(View activityRootView,
                                   boolean isSoftKeyboardOpened) {
        this.activityRootView = activityRootView;
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        // 参考：https://my.oschina.net/u/3760785/blog/4650973
        final Rect visibleRect = new Rect();
        activityRootView.getWindowVisibleDisplayFrame(visibleRect);
        int inVisibleHeight = activityRootView.getRootView().getHeight() - visibleRect.bottom;

        // 键盘弹出时rootInvisibleHeight=键盘高度 + 底部NavigationBar（安卓三大金刚）高度
        // 键盘没弹出时，rootInvisibleHeight=底部NavigationBar（安卓三大金刚）高度,
        // 如果三大金刚是屏幕外的实体按键（比如三星S6，魅族，华为Mate10之类的）不在屏幕范围内，无需考虑
        // 三大金刚一般高度150左右，基本在200以内。
        // Freeman测试结果：荣耀9x，EMUI10.1.0(安卓10.0) 环境下输出高度：835。  魅族5，Flyme 6.3.5.0A(安卓6.0)下输出高度506
        System.out.println("键盘高度："+inVisibleHeight);
        int limit = 260; //取值应大于三大金刚高度，小于可能的最小键盘高度
        if (!isSoftKeyboardOpened && inVisibleHeight >= limit) { // 键盘弹出
            isSoftKeyboardOpened = true;
            notifyOnSoftKeyboardOpened(inVisibleHeight);
        } else if (isSoftKeyboardOpened && inVisibleHeight < limit) { // 键盘收起
            isSoftKeyboardOpened = false;
            notifyOnSoftKeyboardClosed();
        }
    }

    public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
    }

    public boolean isSoftKeyboardOpened() {
        return isSoftKeyboardOpened;
    }

    /**
     * Default value is zero (0)
     *
     * @return last saved keyboard height in px
     */
    public int getLastSoftKeyboardHeightInPx() {
        return lastSoftKeyboardHeightInPx;
    }

    public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.add(listener);
    }

    public void removeSoftKeyboardStateListener(
            SoftKeyboardStateListener listener) {
        listeners.remove(listener);
    }

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;

        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardOpened(keyboardHeightInPx);
            }
        }
    }

    private void notifyOnSoftKeyboardClosed() {
        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardClosed();
            }
        }
    }
}
